// Loesung_von_Aufgabe_6.9_2_Kreiswelle_3D_animiert

// Kreiswelle 3D animiert

float skalierung = 10; // Gibt die Größe einer Gitterzelle an
float rotationX = PI/4; // Rotation um die x-Achse (Startwert entspricht 45°)
float rotationZ = 0; // Rotation um die z-Achse
float positionZ = 0; // Verschiebung entlang der z-Achse
float[][] Kreiswelle = new float[50][50]; // zweidimensionales Array

void setup()
{
  size(750, 750, P3D);
}

/* Die folgende Funktion wird aufgerufen, wenn die Maustaste gedrückt ist
 und die Maus bewegt wird */
void mouseDragged()
{
  /* Die Differenz der Mauskoordinaten (aktuelle Position und vorherige
   Position) wird verkleinert und zur Rotation entlang der x- bzw. z-Achse 
   addiert */
  rotationX += (mouseY - pmouseY) * -0.01;
  rotationZ += (mouseX - pmouseX) * -0.01;
}

// Die folgende Funktion ändert die Werte durch das Drehen des Mausrades
void mouseWheel(MouseEvent event)
{
  positionZ += event.getCount() * 100;
}

void draw()
{
  // Das zweidimensionale Array wird mit Werten gefüllt 
  for (int y = 0; y < 50; y++)
  {
    for (int x = 0; x < 50; x++)
    {
      float r = sqrt(pow(x - 25, 2) + pow(y - 25, 2));
      Kreiswelle[x][y] = 2*sin(r * 0.5 - millis() / 1000.0);
    }
  }

  colorMode(RGB, 255, 255, 255); // Farbraum RGB für den Hintergrund
  background(255, 255, 255);
  stroke(0, 0, 0);
  strokeWeight(1);

  translate(width / 2, height / 2, 0); // Die Null dient hier als Hinweis, dass die z-Koordinate nicht verändert wird
  rotateX(rotationX);
  rotateZ(rotationZ);
  translate(0, 0, positionZ); // Das Koordinatensystem kann mit dem Mausrad in z-Richtung verschoben werden

  colorMode(HSB, 360, 100, 100); // Farbraum HSB für die Kreiswelle

  // Zeichnet die stehende Welle als eine mit Dreiecken dargestellte Oberfläche
  for (int y = 0; y < 50 - 1; y++)
  {
    beginShape(TRIANGLE_STRIP); // Siehe Abbildung in der Referenz zur Funktion beginShape()
    for (int x = 0; x < 50; x++)
    {    
      // Die Farben werden entsprechend den Elongationen der stehenden Welle angepasst (HSB)
      fill(Kreiswelle[x][y] * 50 + 180, 100, 100);
      vertex((x - 25) * skalierung, (y - 25) * skalierung, Kreiswelle[x][y] * skalierung); 
      vertex((x - 25) * skalierung, (y - 25 + 1) * skalierung, Kreiswelle[x][y + 1] * skalierung);
    }
    endShape();
  }
}